// #include "kal_general_types.h"
#include "os_config.h"
// #include "globle_include.h"

#include <stdlib.h>
#include <stdio.h>

#include <string.h>

#include "msgqueue_v2.h"

//#include "FreeRTOS_api_delay_custom.h"


#define DEFAULT_MSGQ_NAME  "msgq"

#if defined(RT_USING_ULOG)
#define LOG_TAG              "OSmsg"
#define LOG_LVL              LOG_LVL_WARNING // LOG_LVL_INFO
#include <ulog.h>

#define MSQ_LOG       	rt_kprintf
#define MSQ_LOG2		rt_kprintf	
#define MSQ_LOG3		rt_kprintf


#else

#define MSQ_LOG(...)  //trace_hw_print
#define MSQ_LOG2  rt_kprintf
#define MSQ_LOG3   rt_kprintf
#endif

msg_queue_id msg_queue_create(const char *pname,size_t msg_size, size_t msg_numitems)
{
	msg_queue_id msgid;
	uint32_t len;

	if(!pname)
		return NULL;

	len = strlen(pname);
	if(len == 0)
		return NULL;
	
	msgid = get_ctrl_buffer(sizeof(msg_queue_t));
	if(msgid == NULL){
		return NULL;
	}
	
	memset(msgid,0,sizeof(msg_queue_t));

	strncpy(msgid->pname,pname,MSG_QUEUE_NAME_LEN_MAX);

	msgid->msg_size = msg_size;

	#if defined(__FreeRTOS__)
	msgid->msg_qu = xQueueCreate(msg_numitems,msg_size); 
	#elif defined(__RTT_OS__)
	msgid->msg_qu = rt_mq_create(msgid->pname, msg_size,
				msg_numitems, RT_IPC_FLAG_FIFO);
	#endif

	if(msgid->msg_qu == NULL){
		MSQ_LOG3("msg q c fail %s\n",pname);
		free_ctrl_buffer(msgid);		
		return NULL;
	}

	MSQ_LOG("msg q c %s :%d ,%d\n",msgid->pname,msg_size,msg_numitems);
		
	return msgid;

}

int msg_queue_free(msg_queue_id msgid)
{

	if(msgid == NULL)
		return -1;

	MSQ_LOG("msg q free %s\n",msgid->pname);

	#if defined(__FreeRTOS__)
	vQueueDelete(msgid->msg_qu);
	#elif defined(__RTT_OS__)
	rt_mq_delete(msgid->msg_qu);
	#endif

	free_ctrl_buffer(msgid);

	return 0;
	
}


#if defined(ENABLE_FREERTOS_SYSAPI)
int msg_enqueue(msg_queue_id msgid,void * pmsg)
{

	BaseType_t err;

	//ASSERT(!systemIsISR());

	if(msgid == NULL || pmsg == NULL)
		return -1;

	err=OS_SEND_MSG(msgid->msg_qu,pmsg,MSG_QUEUE_V2_DELAY /* 10 */);

	//MSQ_LOG("msq %s +\n",msgid->pname);
	
	if(err == pdPASS)
	 	return 0;
	 else
	 {
	 	//MSQ_LOG_HW("msg en err:%s\n",msgid->pname);
	 	return -1;
	 }
}

int msg_enqueue_nowait(msg_queue_id msgid,void * pmsg)
{	
	BaseType_t err;

	//ASSERT(!systemIsISR());

	if(msgid == NULL || pmsg == NULL)
		return -1;

	err=OS_SEND_MSG(msgid->msg_qu,pmsg,0);

	//MSQ_LOG("msq %s ^\n",msgid->pname);
	
	if(err == pdPASS)
	 	return 0;
	 else
	 {
	 	//MSQ_LOG_HW("msg en 2 err:%s\n",msgid->pname);
	 	return -1;
	 }
}


int msg_enqueue_isr(msg_queue_id msgid,void * pmsg)
{

	BaseType_t err;

	if(msgid == NULL || pmsg == NULL)
		return -1;

	err=xQueueSendFromISR(msgid->msg_qu,pmsg,NULL);


	//MSQ_LOG("msq %s +\n",msgid->pname);
	
	if(err == pdPASS)
	 	return 0;
	 else
	 {
	 	//MSQ_LOG_HW("msg en isr err:%s\n",msgid->pname);
	 	return -1;
	 }
}

int msg_enqueue_nowait_isr(msg_queue_id msgid,void * pmsg)
{	
	BaseType_t err;

	if(msgid == NULL || pmsg == NULL)
		return -1;

	err=xQueueSendFromISR(msgid->msg_qu,pmsg,NULL);


	//MSQ_LOG("msq %s ^\n",msgid->pname);
	
	if(err == pdPASS)
	 	return 0;
	 else
	 {
	 	//MSQ_LOG_HW("msg en 2 isr err:%s\n",msgid->pname);
	 	return -1;
	 }
}

#else
int msg_enqueue(msg_queue_id msgid,void * pmsg)
{

	if(msgid == NULL || pmsg == NULL)
		return -1;

	#if defined(__FreeRTOS__)
	BaseType_t err;
	
	if(!systemIsISR())
		err=OS_SEND_MSG(msgid->msg_qu,pmsg,MSG_QUEUE_V2_DELAY /* 10 */);
	else
	    err=xQueueSendFromISR(msgid->msg_qu,pmsg,NULL);


	//MSQ_LOG("msq %s +\n",msgid->pname);
	
	if(err == pdPASS)
	 	return 0;
	 else
	 {
	 	MSQ_LOG3("msg en1 err:%s\n",msgid->pname);
	 	return -1;
	 }
	 #elif defined(__RTT_OS__)
	 //rt_kprintf("err1:%x;%s,%s\n",msgid->msg_qu,msgid->pname,get_current_task_name());
	 if(rt_mq_send(msgid->msg_qu,pmsg,msgid->msg_size) ==RT_EOK)
	 	return 0;
	 else
	 {
	 	MSQ_LOG3("msg en1 err:%s\n",msgid->pname);
	 	return -1;
	 }

	 #endif
}


int msg_enqueue_realsize(msg_queue_id msgid,void * pmsg,size_t msg_size)
{

	if(msgid == NULL || pmsg == NULL)
		return -1;

	#if defined(__FreeRTOS__)
	// xQueueSend_custom
	//xQueueSendFromISR_custom
	BaseType_t err;
	
	if(!systemIsISR())
		err=OS_SEND_MSG(msgid->msg_qu,pmsg,MSG_QUEUE_V2_DELAY /* 10 */);
	else
	    err=xQueueSendFromISR(msgid->msg_qu,pmsg,NULL);


	//MSQ_LOG("msq %s +\n",msgid->pname);
	
	if(err == pdPASS)
	 	return 0;
	 else
	 {
	 	MSQ_LOG3("msg en2 err:%s\n",msgid->pname);
	 	return -1;
	 }

	 #elif defined(__RTT_OS__)
	 //rt_kprintf("err2:%x;%s,%s\n",msgid->msg_qu,msgid->pname,get_current_task_name());

	 if(rt_mq_send(msgid->msg_qu,pmsg,msg_size) ==RT_EOK)
	 	return 0;
	 else
	 {
	 	MSQ_LOG3("msg en2 err:%s\n",msgid->pname);
	 	return -1;
	 }

	 #endif
}

int msg_enqueue_waitTick(msg_queue_id msgid,void * pmsg,tick_timeout_t tick)
{

	if(msgid == NULL || pmsg == NULL)
		return -1;

	#if defined(__FreeRTOS__)
	BaseType_t err;
	
	if(!systemIsISR())
		err=OS_SEND_MSG(msgid->msg_qu,pmsg,tick /* 10 */);
	else
	    err=xQueueSendFromISR(msgid->msg_qu,pmsg,NULL);


	//MSQ_LOG("msq %s +\n",msgid->pname);
	
	if(err == pdPASS)
	 	return 0;
	 else
	 {
	 	MSQ_LOG3("msg en3 err:%s\n",msgid->pname);
	 	return -1;
	 }
	 #elif defined(__RTT_OS__)
	//rt_kprintf("err3:%x;%s,%s\n",msgid->msg_qu,msgid->pname,get_current_task_name());
	 if(rt_mq_send(msgid->msg_qu,pmsg,msgid->msg_size) ==RT_EOK)
	 	return 0;
	 else
	 {
	 	MSQ_LOG3("msg en3 err:%s\n",msgid->pname);
	 	return -1;
	 }

	 #endif
}


int msg_enqueue_nowait(msg_queue_id msgid,void * pmsg)
{	

	if(msgid == NULL || pmsg == NULL)
		return -1;

	#if defined(__FreeRTOS__)
	BaseType_t err;

	if(!systemIsISR())
		err=OS_SEND_MSG(msgid->msg_qu,pmsg,0);
	else
	    err=xQueueSendFromISR(msgid->msg_qu,pmsg,NULL);


	//MSQ_LOG("msq %s ^\n",msgid->pname);
	
	if(err == pdPASS)
	 	return 0;
	 else
	 {
	 	MSQ_LOG3("msg en4 err:%s\n",msgid->pname);
	 	return -1;
	 }

	 #elif defined(__RTT_OS__)
	 //rt_kprintf("err4:%x;%s,%s\n",msgid->msg_qu,msgid->pname,get_current_task_name());
	 if(rt_mq_send(msgid->msg_qu,pmsg,msgid->msg_size) ==RT_EOK)
	 	return 0;
	 else
	 {
	 	MSQ_LOG3("msg en4 err:%s\n",msgid->pname);
	 	return -1;
	 }

	 #endif
}
#endif

int msg_dequeue(msg_queue_id msgid,void * pmsg)
{	
	#if defined(__FreeRTOS__)
	BaseType_t err;

	if(msgid == NULL)
		return -1;

	err = OS_RECV_MSG(msgid->msg_qu, pmsg, portMAX_DELAY);

	//MSQ_LOG("msq %s -\n",msgid->pname);

	if(err == pdTRUE)
		return 0;
	else
		return -1;

	#elif defined(__RTT_OS__)

	 if(rt_mq_recv (msgid->msg_qu,pmsg,
			msgid->msg_size, RT_WAITING_FOREVER) == RT_EOK)
		return 0;
	 else
	  	return -1;

	 #endif
}

int msg_dequeue_waitTick(msg_queue_id msgid,void * pmsg,tick_timeout_t tick)
{	
	#if defined(__FreeRTOS__)

	BaseType_t err;

	if(msgid == NULL)
		return -1;

	err = OS_RECV_MSG(msgid->msg_qu, pmsg, tick /* portMAX_DELAY */);

	//MSQ_LOG("msq %s -\n",msgid->pname);

	if(err == pdTRUE)
		return 0;
	else
		return -1;

	#elif defined(__RTT_OS__)

	 if(rt_mq_recv (msgid->msg_qu,pmsg,
			msgid->msg_size, tick) == RT_EOK)
		return 0;
	 else
	  	return -1;

	 #endif
}

int msg_dequeue_clean(msg_queue_id msgid)
{	
	void * pbuf;
	int count;

	if(msgid == NULL)
		return -1;

	pbuf = get_ctrl_buffer(msgid->msg_size);

	if(pbuf == NULL)
		return -1;


	count = 0;

	while(1){	

		#if defined(__FreeRTOS__)
		if(OS_RECV_MSG(msgid->msg_qu,pbuf,0) == pdFALSE)
			break; 	
		#elif defined(__RTT_OS__)
		if(rt_mq_recv (msgid->msg_qu,pbuf,
			msgid->msg_size, 0) != RT_EOK)
			break; 	
		#endif
		++count;
	}

	free_ctrl_buffer(pbuf);

	//MSQ_LOG("msq X %d\n",count);

	return count;
}


